package yang.VirtualMachine.chapter9.asm;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import yang.VirtualMachine.chapter9.ClassUtil;

public class AsmHelloWorld extends ClassLoader implements Opcodes {
	
	public static void main(final String args[]) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, IOException {
		// COMPUTE_MAXS:自动计算最大局部变量表，最深操作数栈
		// COMPUTE_FRAMES:自动计算栈映射帧（此标记隐含COMPUTE_MAXS）
		ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
		cw.visit(V1_7, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
		
		// AccessFlag name	descriptor(变量I:int 方法:(参数)返回值)
		MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
		mw.visitVarInsn(ALOAD, 0);
		mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
		mw.visitInsn(RETURN);
		mw.visitMaxs(0, 0);
		mw.visitEnd();
		
		mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "(Ljava/lang/String;)V", null, null);
		mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
		mw.visitLdcInsn("Hello World");
		mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
		mw.visitInsn(RETURN);
		mw.visitMaxs(0, 0);
		mw.visitEnd();
		byte[] code = cw.toByteArray();
		
		AsmHelloWorld loader = new AsmHelloWorld();
		Class exampleClass = loader.defineClass("Example", code, 0, code.length);
		exampleClass.getMethods()[0].invoke(null, new Object[] {null});
		
		ClassUtil.write2File(code, "D:\\A.class");
	}
}
